package com.accenture.fd.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFPictureData;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.accenture.fd.entity.DtoToSource;
import com.accenture.fd.service.ClassDesignService;
import com.accenture.fd.utils.generator.model.ClassToExcelModel;
import com.accenture.fd.utils.generator.model.FieldListDTO;
import com.accenture.fd.utils.generator.model.MethodListDTO;

import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.WorkbookUtil;

@CrossOrigin
@RestController
public class ExportClassController {

	private static final String TEMPLATE_PATH = "/doc/仕様書/KKPM_クラス仕様書（自検協情報取得ロジック）.xls"; // 模版路径 (需确认是否放在项目,如果放在项目需要做改动)
	private static final String SHEET_NAME = "WP30206 クラス仕様書"; // sheet名称
	private static final String NEW_SHEET_NAME = "WP30206_クラス仕様書"; // sheet名称
	@Autowired
	private ClassDesignService classDesignService;
	

	/**
	 * CLASS一覧取得
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping("/searchByClassID")
	public ClassToExcelModel searchByClassID(HttpServletRequest request) {

		ClassToExcelModel classModel = classDesignService.getClassDesignModel(
				request.getParameterMap().get("screenId")[0], request.getParameterMap().get("classId")[0]);
		return classModel;
	}

	@RequestMapping("/registerClass")
	public void registerClass(@RequestBody ClassToExcelModel ctmModel, HttpServletResponse response) {

		String filePath = ExportClassController.class.getResource(TEMPLATE_PATH).getPath();

		InputStream is = null;
		try {
			String path = URLDecoder.decode(filePath, "UTF-8");
			is = new FileInputStream(new File(path));
			Workbook wb = WorkbookFactory.create(is);
			Sheet sheet = WorkbookUtil.getOrCreateSheet(wb, SHEET_NAME);

			// フィールドリスト.サイズ＞２の場合、新しいシートを作成する
			if (ctmModel.getFieldList().size() > 2) {
				setDetailsByNewSheet(ctmModel, sheet, wb);
			} else {
				// 既存シートを使う
				setDetailsByExistingSheet(ctmModel, sheet, wb);
			}

			response.setContentType("application/vnd.ms-excel;charset=utf-8");
			String name = ctmModel.getFieldClassPhysicsNm();
			response.setHeader("Content-Disposition", "attachment;filename=" + "KKPM_クラス仕様書（" + name + "）.xlsx");
			ServletOutputStream out = null;
			out = response.getOutputStream();
			wb.write(out);
			out.flush();
			is.close();
			IoUtil.close(out);
		} catch (IOException | EncryptedDocumentException | InvalidFormatException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
		//TB00011登录
		List<DtoToSource> saveList = new ArrayList<>();
		for(int i = 0; i<ctmModel.getFieldList().size(); i++) {
			DtoToSource dto = new DtoToSource();
			dto.setScreenId(ctmModel.getScreenId());
			dto.setClassId(ctmModel.getFieldPackageNm() + "." +ctmModel.getFieldClassPhysicsNm());
			dto.setClassComment(ctmModel.getClassId());
			dto.setParentClass(ctmModel.getFieldImplClassNm());
			dto.setInterfaceClass(ctmModel.getFieldInterface());
			dto.setNameKanji(ctmModel.getFieldList().get(i).getFieldDefinition());
			dto.setNamePhysics(ctmModel.getFieldList().get(i).getFieldSummary());
			dto.setFieldType("String");
			dto.setCreateStatus("1");
			saveList.add(dto);
		}
		
		
		classDesignService.saveDesignDtoList(saveList);
		
	}

	private void setDetailsByExistingSheet(ClassToExcelModel ctmModel, Sheet sheet, Workbook wb) {

		Sheet newSheet = WorkbookUtil.getOrCreateSheet(wb, NEW_SHEET_NAME);
		newSheet.setDisplayGridlines(false);// 设置不显示网格线

		// 复制列宽带
		for (int i = 0; i < 11; i++) {
			newSheet.setColumnWidth(i, sheet.getColumnWidth(i));
		}
		// setHead
		for (int i = 0; i < 27; i++) {
			Row distRow = newSheet.createRow(i);
			Row sourceRow = sheet.getRow(i);
			if (sourceRow != null) {
				copyRow(sheet, newSheet, sourceRow, distRow);
			}
		}
		// setField
		for (int j = 0; j < ctmModel.getFieldList().size(); j++) {
			FieldListDTO fld = ctmModel.getFieldList().get(j);
			newSheet.getRow(j + 22).getCell(0).setCellValue(j + 1);
			newSheet.getRow(j + 22).getCell(1).setCellValue(fld.getFieldDefinition());
			newSheet.getRow(j + 22).getCell(4).setCellValue(fld.getFieldSummary());
			newSheet.getRow(j + 22).getCell(7).setCellValue(fld.getFieldmiddleRemarks());
		}
		// setMethod
		for (int l = 0; l < ctmModel.getMethodList().size(); l++) {
			MethodListDTO mld = ctmModel.getMethodList().get(l);
			Row distFieldRow = newSheet.createRow(l + 27);
			Row sourceFieldRow = sheet.getRow(27);
			if (sourceFieldRow != null) {
				copyRow(sheet, newSheet, sourceFieldRow, distFieldRow);
			}
			newSheet.getRow(l + 27).getCell(0).setCellValue(l + 1);
			newSheet.getRow(l + 27).getCell(1).setCellValue(mld.getMethodDefinition());
			newSheet.getRow(l + 27).getCell(4).setCellValue(mld.getMethodSummary());
			newSheet.getRow(l + 27).getCell(7).setCellValue(mld.getFootRemarks());
		}

		setPicture(newSheet, wb);
		// パッケージ名を設定
		newSheet.getRow(3).getCell(2).setCellValue(ctmModel.getFieldPackageNm());
		// クラス名（物理）を設定
		newSheet.getRow(4).getCell(2).setCellValue(ctmModel.getFieldClassPhysicsNm());
		// スコープ／修飾子を設定
		newSheet.getRow(5).getCell(2).setCellValue("public");
		// 継承クラスを設定
		newSheet.getRow(6).getCell(2).setCellValue(ctmModel.getFieldImplClassNm());
		// アノテーションを設定
		newSheet.getRow(5).getCell(7).setCellValue(ctmModel.getFieldAnnotation());
		// 実装インタフェースを設定
		newSheet.getRow(6).getCell(7).setCellValue(ctmModel.getFieldInterface());
		// 概要を設定
		newSheet.createRow(8).createCell(0).setCellValue(ctmModel.getFieldClassInfo());
		// 備考を設定
		newSheet.createRow(14).createCell(0).setCellValue(ctmModel.getFieldTopRemarks());

		wb.removeSheetAt(wb.getSheetIndex(sheet));
		newSheet.setZoom(80);
	}

	private void setDetailsByNewSheet(ClassToExcelModel ctmModel, Sheet sheet, Workbook wb) {
		Sheet newSheet = WorkbookUtil.getOrCreateSheet(wb, NEW_SHEET_NAME);
		newSheet.setDisplayGridlines(false);// 设置不显示网格线

		// 复制列宽带
		for (int i = 0; i < 11; i++) {
			newSheet.setColumnWidth(i, sheet.getColumnWidth(i));
		}

		// setHead
		for (int i = 0; i < 22; i++) {
			Row distRow = newSheet.createRow(i);
			Row sourceRow = sheet.getRow(i);
			if (sourceRow != null) {
				copyRow(sheet, newSheet, sourceRow, distRow);
			}
		}

		// setField
		int count = 0;
		for (int j = 0; j < ctmModel.getFieldList().size(); j++) {
			FieldListDTO fld = ctmModel.getFieldList().get(j);
			Row distFieldRow = newSheet.createRow(j + 22);
			Row sourceFieldRow = sheet.getRow(22);
			if (sourceFieldRow != null) {
				copyRow(sheet, newSheet, sourceFieldRow, distFieldRow);
			}
			newSheet.getRow(j + 22).getCell(0).setCellValue(j + 1);
			newSheet.getRow(j + 22).getCell(1).setCellValue(fld.getFieldDefinition());
			newSheet.getRow(j + 22).getCell(4).setCellValue(fld.getFieldSummary());
			newSheet.getRow(j + 22).getCell(7).setCellValue(fld.getFieldmiddleRemarks());
			count++;
		}
		// setMethodTemplate
		int num = count + 22;
		for (int k = 0; k < 3; k++) {
			Row distMTRow = newSheet.createRow(num + k);
			Row sourceMTRow = sheet.getRow(24 + k);
			if (sourceMTRow != null) {
				copyRow(sheet, newSheet, sourceMTRow, distMTRow);
			}
			count++;
		}

		// setMethod
		num = count + 22;
		for (int l = 0; l < ctmModel.getMethodList().size(); l++) {
			MethodListDTO mld = ctmModel.getMethodList().get(l);
			Row distFieldRow = newSheet.createRow(l + num);
			Row sourceFieldRow = sheet.getRow(27);
			if (sourceFieldRow != null) {
				copyRow(sheet, newSheet, sourceFieldRow, distFieldRow);
			}
			newSheet.getRow(l + num).getCell(0).setCellValue(l + 1);
			newSheet.getRow(l + num).getCell(1).setCellValue(mld.getMethodDefinition());
			newSheet.getRow(l + num).getCell(4).setCellValue(mld.getMethodSummary());
			newSheet.getRow(l + num).getCell(7).setCellValue(mld.getFootRemarks());
		}

		setPicture(newSheet, wb);
		// パッケージ名を設定
		newSheet.getRow(3).getCell(2).setCellValue(ctmModel.getFieldPackageNm());
		// クラス名（物理）を設定
		newSheet.getRow(4).getCell(2).setCellValue(ctmModel.getFieldClassPhysicsNm());
		// スコープ／修飾子を設定
		newSheet.getRow(5).getCell(2).setCellValue("public");
		// 継承クラスを設定
		newSheet.getRow(6).getCell(2).setCellValue(ctmModel.getFieldImplClassNm());
		// アノテーションを設定
		newSheet.getRow(5).getCell(7).setCellValue(ctmModel.getFieldAnnotation());
		// 実装インタフェースを設定
		newSheet.getRow(6).getCell(7).setCellValue(ctmModel.getFieldInterface());
		// 概要を設定
		newSheet.createRow(8).createCell(0).setCellValue(ctmModel.getFieldClassInfo());
		// 備考を設定
		newSheet.createRow(14).createCell(0).setCellValue(ctmModel.getFieldTopRemarks());

		wb.removeSheetAt(wb.getSheetIndex(sheet));
		newSheet.setZoom(80);

	}

	@SuppressWarnings("deprecation")
	private void copyRow(Sheet sheet, Sheet newSheet, Row sourceRow, Row distRow) {
		// 设置高度
		distRow.setHeight(sourceRow.getHeight());
		// 复制合并的单元格
		for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
			CellRangeAddress sourceRange = sheet.getMergedRegion(i);
			if (sourceRange.getFirstRow() == sourceRow.getRowNum()) {
				CellRangeAddress distRange = new CellRangeAddress(distRow.getRowNum(),
						distRow.getRowNum() + (sourceRange.getLastRow() - sourceRange.getFirstRow()),
						sourceRange.getFirstColumn(), sourceRange.getLastColumn());
				newSheet.addMergedRegion(distRange);
			}
		}
		// 复制单元格
		for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
			distRow.createCell(i).setCellStyle(sourceRow.getCell(i).getCellStyle());
			int sourceCellType = sourceRow.getCell(i).getCellType();
			distRow.getCell(i).setCellType(sourceCellType);
			switch (sourceCellType) {
			case Cell.CELL_TYPE_NUMERIC:
				if (DateUtil.isCellDateFormatted(sourceRow.getCell(i))) {
					distRow.getCell(i).setCellValue(sourceRow.getCell(i).getDateCellValue());
				} else {
					distRow.getCell(i).setCellValue(sourceRow.getCell(i).getNumericCellValue());
				}
				break;
			case Cell.CELL_TYPE_STRING:
				distRow.getCell(i).setCellValue(sourceRow.getCell(i).getRichStringCellValue());
				break;
			case Cell.CELL_TYPE_BOOLEAN:
				distRow.getCell(i).setCellValue(sourceRow.getCell(i).getBooleanCellValue());
				break;
			case Cell.CELL_TYPE_ERROR:
				distRow.getCell(i).setCellValue(sourceRow.getCell(i).getErrorCellValue());
				break;
			case Cell.CELL_TYPE_FORMULA:
				distRow.getCell(i).setCellValue(sourceRow.getCell(i).getCellFormula());
				break;
			default:
				break;

			}
		}
	}

	@SuppressWarnings({ "unchecked", "deprecation" })
	private void setPicture(Sheet sheet, Workbook wb) {

		List<HSSFPictureData> pictures = (List<HSSFPictureData>) wb.getAllPictures();
		HSSFPictureData picData = pictures.get(0);

		// 画图的顶级管理器，一个sheet只能获取一个（一定要注意这点）
		HSSFPatriarch patriarch = (HSSFPatriarch) sheet.createDrawingPatriarch();
		// anchor主要用于设置图片的属性
		HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 128, 64, (short) 2, 0, (short) 8, 2);
		anchor.setAnchorType(3);
		// 插入图片
		patriarch.createPicture(anchor, wb.addPicture(picData.getData(), HSSFWorkbook.PICTURE_TYPE_JPEG));

	}

}
